#ifndef ASM_THREAD_INFO_H
#define ASM_THREAD_INFO_H

#include <seminix/const.h>
#include <asm/memory.h>

#define KERNEL_DS       UL(-1)
#define USER_DS         ((UL(1) << MAX_USER_VA_BITS) - 1)

#define DEFAULT_MAP_WINDOW_64	(UL(1) << VA_BITS)
#define TASK_SIZE_64		    (UL(1) << vabits_user)

#define DEFAULT_MAP_WINDOW	DEFAULT_MAP_WINDOW_64
#define TASK_SIZE		    TASK_SIZE_64

#define STACK_TOP_MAX		DEFAULT_MAP_WINDOW_64
#define TASK_UNMAPPED_BASE	(PAGE_ALIGN(DEFAULT_MAP_WINDOW / 4))

#define STACK_TOP       STACK_TOP_MAX

#define TIF_SIGPENDING      0
#define TIF_NEED_RESCHED	1
#define TIF_FOREIGN_FPSTATE	2	/* CPU's FP state is not current's */
#define TIF_FSCHECK         3   /* Check FS is USER_DS on return */
#define TIF_POLLING_NRFLAG  5
#define TIF_RESTORE_SIGMASK	20
#define TIF_SVE			    23	/* Scalable Vector Extension in use */
#define TIF_SVE_VL_INHERIT	24	/* Inherit sve_vl_onexec across exec */

#define _TIF_SIGPENDING		  (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED	  (1 << TIF_NEED_RESCHED)
#define _TIF_FOREIGN_FPSTATE  (1 << TIF_FOREIGN_FPSTATE)
#define _TIF_FSCHECK		  (1 << TIF_FSCHECK)
#define _TIF_POLLING_NRFLAG	  (1 << TIF_POLLING_NRFLAG)
#define _TIF_SVE              (1 << TIF_SVE)

#define _TIF_WORK_MASK		(_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
                             _TIF_FOREIGN_FPSTATE | _TIF_FSCHECK)
#define _TIF_WORK_RESCHED   (_TIF_NEED_RESCHED)

#ifndef __ASSEMBLY__
struct task_struct;

typedef unsigned long mm_segment_t;

/*
 * low level task data that entry.S needs immediate access to.
 */
struct thread_info {
    unsigned long       flags;      /* low level flags */
    mm_segment_t        addr_limit; /* address limit */
#ifdef CONFIG_ARM64_SW_TTBR0_PAN
    u64			ttbr0;		/* saved TTBR0_EL1 */
#endif
    int preempt_count;
};

#define thread_saved_pc(tsk)	\
    ((unsigned long)(tsk->thread.cpu_context.pc))
#define thread_saved_sp(tsk)	\
    ((unsigned long)(tsk->thread.cpu_context.sp))
#define thread_saved_fp(tsk)	\
    ((unsigned long)(tsk->thread.cpu_context.fp))

void arch_setup_new_exec(void);
#define arch_setup_new_exec     arch_setup_new_exec

void arch_release_task_struct(struct task_struct *tsk);

#define INIT_THREAD_INFO(tsk)		\
{									\
    .flags		    = _TIF_FOREIGN_FPSTATE,  \
    .addr_limit	    = KERNEL_DS,		\
    .preempt_count  = INIT_PREEMPT_COUNT,    \
}

#endif /* !__ASSEMBLY__ */
#endif /* !ASM_THREAD_INFO_H */
